using System;
using System.Workflow.Activities;
using System.Workflow.ComponentModel;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.Workflow;
using Microsoft.Crm.Sdk.Query;
using System.Xml;
using System.Text.RegularExpressions;
using System.Web.Services.Protocols;
using System.Data.SqlClient;

namespace CRM4ContractUtilities
{
    [CrmWorkflowActivity("Change Contract Status To Draft", "Contract Utilities")]
    public class ChangeContractStatus : System.Workflow.Activities.SequenceActivity
    {
        /// <summary>
        /// Contract Id
        /// </summary>
        public static DependencyProperty contractIdProperty = DependencyProperty.Register("contractId", typeof(Lookup), typeof(ChangeContractStatus));
        [CrmInput("contractId")]
        [CrmReferenceTarget("contract")]
        public Lookup contractId
        {
            get { return (Lookup)base.GetValue(contractIdProperty); }
            set { base.SetValue(contractIdProperty, value); }
        }

     
        /// <summary>
        /// Database Connection string
        /// </summary>
        public static DependencyProperty databaseConnectionStringProperty = DependencyProperty.Register("databaseConnectionString", typeof(String), typeof(ChangeContractStatus));
        [CrmInput("databaseConnectionString")]
        public String databaseConnectionString
        {
            get { return (String)base.GetValue(databaseConnectionStringProperty); }
            set { base.SetValue(databaseConnectionStringProperty, value); }
        }

        /// <summary>
        /// Contract
        /// </summary>
        public static DependencyProperty newContractIdProperty = DependencyProperty.Register("newContractId", typeof(Lookup), typeof(ChangeContractStatus));
        [CrmOutput("newContractId")]
        [CrmReferenceTarget("contract")]
        public Lookup newContractId
        {
            get { return (Lookup)base.GetValue(newContractIdProperty); }
            set { base.SetValue(newContractIdProperty, value); }
        }

        protected override System.Workflow.ComponentModel.ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {

            IContextService contextService = (IContextService)executionContext.GetService(typeof(IContextService));
            IWorkflowContext context = contextService.Context;
            // Obtain IcrmService so we can call into CRM SDK to retrieve 
            // accounts                
            //ICrmService crmService = context.CreateCrmService();

            //get text based on 
            if (contractId != null)
            {
                ChangeStatus(contractId.Value.ToString());
            }


            return ActivityExecutionStatus.Closed;


        }
        /// <summary>
        /// Connects to database and update contract status
        /// </summary>
        /// <param name="sourceContractId"></param>
        private void ChangeStatus(string sourceContractId)
        {
            try
            {
                
                int statusValue = 1; //default value for draft
                int stateCodeValue = 0; //default value for draft
               
                using (SqlConnection connection = new SqlConnection(databaseConnectionString))
                {
                    connection.Open();
                    using (SqlCommand cmd = new SqlCommand("", connection))
                    {
                        //Update Contract Line
                        cmd.CommandText = "Update ContractDetailBase set StateCode = " + stateCodeValue + ", StatusCode = " + statusValue + " Where ContractId = '" + contractId.Value.ToString() + "'";
                        cmd.ExecuteNonQuery();
                        
                        //Update Contract
                        cmd.CommandText = "Update ContractBase set StateCode = " + stateCodeValue + ", StatusCode = " + statusValue + " Where ContractId = '" + contractId.Value.ToString() + "'";
                        cmd.ExecuteNonQuery();
                        
                    }
                    connection.Close();
                }

                this.newContractId = new Lookup("contract", new Guid(sourceContractId));



            }            
            catch (Exception ex)
            {
                throw (ex);
            }

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fielName"></param>
        /// <returns></returns>
        private Boolean IsValidContractField(string fielName)
        {
            Boolean IsValid = true;
  
            
            if (fielName.Equals("contractid") || fielName.Equals("contractnumber") ||
                fielName.Equals("billingendon") || fielName.Equals("billingstarton") ||
                fielName.Equals("activeon") || fielName.Equals("expireson") ||
                fielName.Equals("statecode") || fielName.Equals("statuscode") 
                )
            {
                IsValid = false;
            }
            return IsValid;
        
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fielName"></param>
        /// <returns></returns>
        private Boolean IsValidContractLineField(string fielName)
        {
            Boolean IsValid = true;
            
            if (fielName.Equals("contractid") || fielName.Equals("contractdetailid") ||                
                fielName.Equals("activeon") || fielName.Equals("expireson") ||
                fielName.Equals("statecode") || fielName.Equals("statuscode"))
            {
                IsValid = false;
            }
            return IsValid;

        }


        /// <summary>
        /// Retrieves the Contract objects
        /// </summary>
        /// <param name="myService">The CRM Service</param>
        /// <param name="searchId">The Search Id String</param>
        /// <returns>Contract Object</returns>
        private DynamicEntity RetrieveDynamicEntityForContract(ICrmService myService, string contractid)
        {
            DynamicEntity myDynamicEntity = null;
            try
            {

                QueryExpression query = new QueryExpression();
                query.ColumnSet = new AllColumns();



                query.EntityName = EntityName.contract.ToString();
                FilterExpression filter = new FilterExpression();
                query.Criteria = filter;

                ConditionExpression hasAccountNoOf = new ConditionExpression();
                filter.Conditions.Add(hasAccountNoOf);

                hasAccountNoOf.AttributeName = "contractid";
                hasAccountNoOf.Operator = ConditionOperator.Equal;
                hasAccountNoOf.Values = new string[] { contractid };


                // Retrieve the contact.
                RetrieveMultipleRequest req = new RetrieveMultipleRequest();
                req.Query = query;
                req.ReturnDynamicEntities = true;

                RetrieveMultipleResponse res
                   = (RetrieveMultipleResponse)myService.Execute(req);

                if (res.BusinessEntityCollection.BusinessEntities.Count == 1)
                {

                    foreach (BusinessEntity be in res.BusinessEntityCollection.BusinessEntities)
                    {
                        myDynamicEntity = (DynamicEntity)be;
                        break;
                    }
                }


            }
            catch (Exception ex)
            {
                //throw (ex);
            }
            return myDynamicEntity;

        }

        private void CreateContractLines(ICrmService crmService, string sourceContractId, string newContractId, DateTime newStartDate, DateTime newEndDate)
        {

            BusinessEntityCollection sourceContractlines = RetrieveContractLinesFromContract(crmService, sourceContractId);
            if (sourceContractlines != null && sourceContractlines.BusinessEntities.Count > 0)
            {
                foreach (BusinessEntity newlineEntity in sourceContractlines.BusinessEntities)
                {
                    DynamicEntity dynamicLineEntity = (DynamicEntity)newlineEntity;

                    //invoice is created now update the existing orderline with the Invoice Number			
                    DynamicEntity newDynamicContractLine = new DynamicEntity();
                    newDynamicContractLine.Name = EntityName.contractdetail.ToString();

                    //newDynamicContract.Properties = dynamicContract.Properties;
                    newDynamicContractLine.Properties = new PropertyCollection();
                    foreach (Property per in dynamicLineEntity.Properties)
                    {
                        if (IsValidContractLineField(per.Name))
                        {
                            newDynamicContractLine.Properties.Add(per);
                        }
                    }

                    
                    newDynamicContractLine.Properties.Add(new LookupProperty("contractid", CrmTypes.CreateLookup(EntityName.contract.ToString(),new Guid(newContractId))));
                    newDynamicContractLine.Properties.Add(new CrmDateTimeProperty("activeon", CrmTypes.CreateCrmDateTimeFromUser(newStartDate)));
                    newDynamicContractLine.Properties.Add(new CrmDateTimeProperty("expireson", CrmTypes.CreateCrmDateTimeFromUser(newEndDate)));
                    



                    TargetCreateDynamic targetCreate = new TargetCreateDynamic();
                    targetCreate.Entity = newDynamicContractLine;

                    // Create the request object.
                    CreateRequest create = new CreateRequest();
                    create.Target = targetCreate;


                    CreateResponse created = (CreateResponse)crmService.Execute(create);


                }
            }
        }

        /// <summary>
        /// Retrieves the Account objects
        /// </summary>
        /// <param name="myService">The CRM Service</param>
        /// <param name="searchId">The Search Id String</param>
        /// <returns>Account Identifier</returns>
        private BusinessEntityCollection RetrieveContractLinesFromContract(ICrmService myService, string contractId)
        {

            try
            {



                QueryExpression query = new QueryExpression();
                query.ColumnSet = new AllColumns();

                query.EntityName = EntityName.contractdetail.ToString();
                FilterExpression filter = new FilterExpression();
                query.Criteria = filter;

                ConditionExpression hasContractId = new ConditionExpression();
                hasContractId.AttributeName = "contractid";
                hasContractId.Operator = ConditionOperator.Equal;
                hasContractId.Values = new string[] { contractId };

                filter.Conditions.Add(hasContractId);

                // Retrieve the contact.
                RetrieveMultipleRequest req = new RetrieveMultipleRequest();
                req.Query = query;
                req.ReturnDynamicEntities = true;

                RetrieveMultipleResponse res
                   = (RetrieveMultipleResponse)myService.Execute(req);

                return res.BusinessEntityCollection;

            }
            catch (Exception ex)
            {
                return null;
            }


        }

    }
}

